//
// Created by LiuYou on 2021/9/5.
//

#ifndef HIGHPERFORMANCELINUXSERVERPROGRAMMING_LINUX2_DBCONNECTIONPOOL_HPP
#define HIGHPERFORMANCELINUXSERVERPROGRAMMING_LINUX2_DBCONNECTIONPOOL_HPP


#include <string>
#include <mysql.h>
#include <list>
#include "Locker.hpp"
#include "../ThreadPool2/Semaphore.hpp"


class DbConnectionPool {
public:
    /**
     * @brief 获取数据库连接
     * <p>
     * 当有请求时，从数据库连接池中返回一个可用连接，更新使用和空闲连接数。
     * @return
     */
    MYSQL* getConnection();

    /**
     * @brief 释放连接
     * <p>
     * 释放当前使用的连接
     * @param conn
     * @return
     */
    bool releaseConnection(MYSQL* conn);

    /**
     * @brief 获取连接
     * <p>
     * 当前空闲的连接数
     * @return
     */
    int getFreeConn();

    /**
     * @brief 销毁所有连接
     * <p>
     * 销毁数据库连接池
     */
    void destroyPool();

public:
    /**
     * @brief 单例模式。
     * @return
     */
    static DbConnectionPool* getInstance();

public:
    void init(const std::string& url, const std::string& user, const std::string& passWord, const std::string& databaseName,
         int port, unsigned int maxConn);

public:
    DbConnectionPool();

//    DbConnectionPool(const std::string& url, const std::string& user, const std::string& passWord,
//                     const std::string& databaseName, int port, unsigned int maxConn);

    ~DbConnectionPool();

private:
    /** 最大连接数。*/
    unsigned int MaxConn;
    /** 当前已使用的连接数。*/
    unsigned int CurConn;
    /** 当前空闲的连接数。*/
    unsigned int FreeConn;

private:
    Locker lock;
    /** 数据库连接池。*/
    std::list<MYSQL*> connList;
    Semaphore reserve;

private:
    /** 主机地址。*/
    std::string url;
    /** 数据库端口号。*/
//    std::string Port;
    int Port;
    /** 登陆数据库用户名。*/
    std::string User;
    /** 登陆数据库密码。*/
    std::string PassWord;
    /** 使用数据库名。*/
    std::string DatabaseName;

};

class DbConnectionRAII {
public:
    DbConnectionRAII(MYSQL** conRaii, DbConnectionPool* poolRaii);

    ~DbConnectionRAII();

private:
    MYSQL* conRAII;
    DbConnectionPool* poolRAII;

};


#endif //HIGHPERFORMANCELINUXSERVERPROGRAMMING_LINUX2_DBCONNECTIONPOOL_HPP
